package com.fuda.uifinder


import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.accessibilityservice.GestureDescription.StrokeDescription
import android.graphics.Path
import android.graphics.Rect
import android.os.Build
import android.util.Log
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import androidx.annotation.RequiresApi
import java.util.concurrent.TimeUnit


class UifinderAccessibilityService : AccessibilityService() {
    private val TAG =UifinderAccessibilityService::class.java.simpleName

    companion object {
    }

    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
    override fun onServiceConnected() {
        super.onServiceConnected()
        Log.d(TAG, "Accessibility service connected.")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e(TAG, "Accessibility service onDestroy.")
    }

    override fun onInterrupt() {
        Log.d(TAG, "Accessibility service onInterrupt.")
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        Log.i(TAG, "onAccessibilityEvent:  $event " )

        // Check if the event is from the guosen app
        if (!event.packageName.contains(
                "com.tdx.androidCCZQ" // 川财证券
                //"com.hexin" // 同花顺,太难搞，代理证券公司的找不到view哪些，基本不支持AccessibilityService
                //"com.guosen" //国信，还可以，可以找到view，但是viewid好像好多没有的
        )) {
            return
        }


        // Get the root node of the event
        val rootNode: AccessibilityNodeInfo? = event.source

        if (rootNode == null){
            Log.e(TAG, "rootNode is null")
            return
        }

        Log.d(TAG, "rootNode: ${rootNode.toString()}")

        // Process the event based on its type
        when (event.eventType) {
            AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED->{
//                processWindowContentChangedEvent(event)
            }

            AccessibilityEvent.TYPE_VIEW_CLICKED -> {
                // Handle view focused events
                processViewClickedEvent(event)
            }

            else -> {
                // Optionally handle other event types
                Log.i(TAG, "else event= $event")
            }
        }
    }

    private fun processWindowContentChangedEvent(event: AccessibilityEvent) {
        val rootNode = rootInActiveWindow ?: return

        // Build the hierarchy as a Node object
        val hierarchyNode = Node.fromAccessibilityNodeInfo(rootNode,"",0)
        // val content = hierarchyNode.serializeToJson()
        val content = Node.buildIndentationString(hierarchyNode)

        val payload = String.format("\nindex, viewId, className, text, path, boundsInScreen, isClickable, isLongClickable\n%s",content)

        Log.d(TAG, payload)
        MyApplication.zenohManager.publish(ZenohManager.responseKeyExpr!!,payload)

        // findChildNodeByPath
//        ________1, null, android.widget.TextView, [交易], 0,0,0,4,1,
//        ________________2, null, android.widget.TextView, [买入], 0,0,0,2,0,0,0,0,2,
//        ______8, null, android.widget.EditText, [请输入交易账号], 0,0,0,8,

        // val path =intArrayOf(0,0,8)
        // ________1, null, android.widget.TextView, [交易], 0,0,0,4,1,
        val path =intArrayOf(0,0,4,1)
        val foundNode = Node.findChildNodeByPath(rootNode, path)
        val pathStr = path.joinToString(prefix = "[", postfix = "]", separator = ", ")
        Log.e(TAG, "findViewByPath foundNode(rootNode,$pathStr): $foundNode")
    }

    private fun processViewClickedEvent(event: AccessibilityEvent) {
        // theNode
        val nodeInfo: AccessibilityNodeInfo = event.source ?: return
        val hierarchyNode = Node.fromAccessibilityNodeInfo(nodeInfo,"",0)
        val contentNode = Node.buildIndentationString(hierarchyNode)
        val payloadNode = String.format("Clicked View: $contentNode\n nodeInfo= $nodeInfo")

        // rootNode
        val rootNode = rootInActiveWindow ?: return
        val hierarchyRootNode = Node.fromAccessibilityNodeInfo(rootNode,"",-1)
        val contentRoot = Node.buildIndentationString(hierarchyRootNode)
        val payloadRoot = String.format("index, viewId, className, text, path, boundsInScreen, isClickable, isLongClickable\n%s",contentRoot)

        val payload = String.format("%s\n\n%s",payloadNode,payloadRoot)

        MyApplication.zenohManager.publish(ZenohManager.responseKeyExpr!!,payload)

        Log.d(TAG, payloadNode)
        TimeUnit.MILLISECONDS.sleep(500)
    }

    fun simulateTouch(rect: Rect){

        Log.e(TAG, "onClick: Simulate Touch")


        // Calculate the center of the bounds
        val centerX = rect.centerX().toFloat()
        val centerY = rect.centerY().toFloat()


        val tap: Path = Path()
        tap.moveTo(centerX, centerY)
        val tapBuilder = GestureDescription.Builder()
        tapBuilder.addStroke(StrokeDescription(tap, 0, 500))
        dispatchGesture(tapBuilder.build(), null, null)
    }

}